﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.Serialization;
using System.ComponentModel.Composition;
using PServiceBus.Core.Interface;
using PServiceBus.Core.Runtime.Transports;
using PServiceBus.Core.Runtime.Messages;

namespace PServiceBus.WCF.NetTcpTransport {
    [Serializable]
    [DataContract]
    [Export(typeof(ITransport))]
    public class NetTcpTransport : ITransport {

        static NetTcpTransport() {
            SerializationBootstrapper.Configure();
        }

        internal Dictionary<string, string> TypeNamespaces { get; set; }

        internal string GlobalTypeNamespace { get; set; }

        public NetTcpTransport() {
            TypeNamespaces = new Dictionary<string, string>();
        }

        #region ITransport Members

        [DataMember]
        public TransportFormat Format { get; set; }

        [DataMember]
        public BindingInfo Binding { get; set; }

        [DataMember]
        public string EndpointAddress { get; set; }

        /// <summary>
        /// Key => parameter name, Value => Property Name of message to map to WCF operation parameters
        /// </summary>
        [DataMember]
        public List<OperationParameter> MethodParameters { get; set; }

        [DataMember]
        public OperationCallInfo OperationContext { get; set; }

        public TransportResponse Send(string message, Dictionary<string, object> messageStructure) {
            var tranResponse = TransportResponse.New<NetTcpTransport>();
            try {
                NetTcpHelper.Invoke(this, MessageMapper.Map(message, messageStructure));
                tranResponse.Success = true;
            } catch (Exception ex) {
                tranResponse.Message = ex.ToString();
            }
            return tranResponse;
        }

        #endregion

        public void DefaultNamespaceTo(string @namespace) {
            GlobalTypeNamespace = @namespace;
        }

        public void AddNamespaceFor<TType>(string @namespace) where TType : class {
            var type = typeof(TType);
            TypeNamespaces[type.Name] = @namespace;
        }
    }
}
